package juc.utils.semaphore;

import java.util.Collection;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;

public class SemaphoreExample4 {
    public static void main(String[] args) throws InterruptedException {
        //final Semaphore semaphore = new Semaphore(5);
        final MySemaphore semaphore = new MySemaphore(5);

        Thread t1 = new Thread() {
            @Override
            public void run() {
                try {
                    //获取所有许可，耗尽
                    semaphore.drainPermits();
                    System.out.println("availablePermits " + semaphore.availablePermits());
                    TimeUnit.SECONDS.sleep(4);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    semaphore.release(5);
                }
                System.out.println("t1 finished");
            }
        };
        t1.start();

        TimeUnit.MILLISECONDS.sleep(50);
        Thread t2 = new Thread() {
            @Override
            public void run() {
                try {
                    //semaphore.acquire();
                    //尝试获取，拿不到就不拿了，不抛异常，不能被中断
                    //boolean b = semaphore.tryAcquire();
                    //带超时的尝试获取，可以被中断
                    boolean b = semaphore.tryAcquire(1,TimeUnit.SECONDS);
                    System.out.println(b ? "Successful" : "failure");
                    TimeUnit.SECONDS.sleep(4);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    semaphore.release();
                }
                System.out.println("t2 finished");
            }
        };
        t2.start();
        TimeUnit.MILLISECONDS.sleep(50);

        //等待信号量的线程数
        System.out.println(semaphore.hasQueuedThreads());
        Collection<Thread> waitingThreads = semaphore.getWaitingThreads();
        for (Thread t : waitingThreads) {
            System.out.println(t);
        }
    }

    static class MySemaphore extends Semaphore {

        public MySemaphore(int permits) {
            super(permits);
        }

        public MySemaphore(int permits, boolean fair) {
            super(permits, fair);
        }

        public Collection<Thread> getWaitingThreads() {
            return super.getQueuedThreads();
        }
    }
}
